package vip.ola.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import vip.ola.core.common.util.RedisUtil;
import vip.ola.core.common.vo.DrawPassageVO;
import vip.ola.core.entity.MchPayPassage;
import vip.ola.core.entity.MchPayPassageExample;
import vip.ola.core.entity.PayPassageAccount;
import vip.ola.core.entity.PayPassageAccountExample;
import vip.ola.core.service.IMchPayPassageService;
import vip.ola.service.dao.mapper.MchPayPassageMapper;
import vip.ola.service.dao.mapper.PayPassageAccountMapper;
import vip.ola.service.dao.mapper.code.CodeUserMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static vip.ola.core.common.constant.CacheKey.HALF_HOURS;
import static vip.ola.core.common.constant.CacheKey.MCH_PAY_PASSAGE;
import static vip.ola.core.common.constant.Constant.PUB_YES;

/**
 * @author: dingzhiwei
 * @date: 2018/5/3
 * @description: 商户支付通道
 */
@Service(interfaceName = "vip.ola.core.service.IMchPayPassageService", version = "1.0.0", retries = -1)
public class MchPayPassageServiceImpl implements IMchPayPassageService {

    @Autowired
    private MchPayPassageMapper mchPayPassageMapper;
    @Autowired
    private PayPassageAccountMapper passageAccountMapper;
    @Autowired
    private CodeUserMapper codeUserMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public int add(MchPayPassage mchPayPassage) {
        int row = mchPayPassageMapper.insertSelective(mchPayPassage);
        redisUtil.delete(MCH_PAY_PASSAGE + mchPayPassage.getMchId() + ":" + mchPayPassage.getProductId());
        return row;
    }

    @Override
    public int update(MchPayPassage mchPayPassage) {
        int row = mchPayPassageMapper.updateByPrimaryKeySelective(mchPayPassage);
        redisUtil.delete(MCH_PAY_PASSAGE + mchPayPassage.getMchId() + ":" + mchPayPassage.getProductId());
        return row;
    }

    @Override
    public int update(MchPayPassage updateMchPayPassage, MchPayPassage queryMchPayPassage) {
        MchPayPassageExample example = new MchPayPassageExample();
        MchPayPassageExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, queryMchPayPassage);
        int row = mchPayPassageMapper.updateByExampleSelective(updateMchPayPassage, example);
        redisUtil.delete(MCH_PAY_PASSAGE + updateMchPayPassage.getMchId() + ":" + updateMchPayPassage.getProductId());
        return row;
    }

    @Override
    public MchPayPassage findById(Integer id) {
        return mchPayPassageMapper.selectByPrimaryKey(id);
    }

    @Override
    public MchPayPassage findByMchIdAndProductId(Long mchId, Integer productId) {
        return redisUtil.get(MCH_PAY_PASSAGE + mchId + ":" + productId, () ->
                        mchPayPassageMapper.findByMchIdAndProductId(mchId, productId)
                , MchPayPassage.class, HALF_HOURS);
    }

    @Override
    public List<MchPayPassage> select(int offset, int limit, MchPayPassage mchPayPassage) {
        MchPayPassageExample example = new MchPayPassageExample();
        example.setOrderByClause("createTime DESC");
        example.setOffset(offset);
        example.setLimit(limit);
        MchPayPassageExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchPayPassage);
        return mchPayPassageMapper.selectByExample(example);
    }

    @Override
    public Integer count(MchPayPassage mchPayPassage) {
        MchPayPassageExample example = new MchPayPassageExample();
        MchPayPassageExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchPayPassage);
        return mchPayPassageMapper.countByExample(example);
    }

    @Override
    public List<MchPayPassage> selectAll(MchPayPassage mchPayPassage) {
        MchPayPassageExample example = new MchPayPassageExample();
        example.setOrderByClause("createTime DESC");
        MchPayPassageExample.Criteria criteria = example.createCriteria();
        setCriteria(criteria, mchPayPassage);
        return mchPayPassageMapper.selectByExample(example);
    }

    @Override
    public List<MchPayPassage> selectAllByMchId(Long mchId, Byte status) {
        MchPayPassage mchPayPassage = new MchPayPassage();
        mchPayPassage.setMchId(mchId);
        if (status != null) {
            mchPayPassage.setStatus(status);
        }
        return selectAll(mchPayPassage);
    }

    public List<DrawPassageVO> getMchPassageByMchId(long mchId) {
        MchPayPassageExample example = new MchPayPassageExample();
        MchPayPassageExample.Criteria criteria = example.createCriteria();
        criteria.andMchIdEqualTo(mchId);
        criteria.andStatusEqualTo(PUB_YES);
        List<MchPayPassage> mchPayPassagesList = mchPayPassageMapper.selectByExample(example);
        List accountIdList = new ArrayList();
        for (MchPayPassage mchPayPassage : mchPayPassagesList) {
            if (mchPayPassage.getIfMode() == 1) {
                Map param = new HashMap<>(2);
                param.put("payPassageId", mchPayPassage.getPayPassageId());
                List<PayPassageAccount> payPassageAccounts = passageAccountMapper.selectAllByPassageId2(param);
                if (CollectionUtils.isEmpty(payPassageAccounts)) {
                    continue;
                }
                for (PayPassageAccount payAccount : payPassageAccounts) {
                    accountIdList.add(payAccount.getPassageMchId());
                }
            } else {
                JSONArray jsonArray = JSONArray.parseArray(mchPayPassage.getPollParam());
                List passageIdList = new ArrayList();
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject o = (JSONObject) jsonArray.get(i);
                    passageIdList.add(o.get("payPassageId"));
                }
                // 根据通道id查询通道子账号
                PayPassageAccountExample passageAccountExample = new PayPassageAccountExample();
                PayPassageAccountExample.Criteria accountCriteria = passageAccountExample.createCriteria();
                accountCriteria.andPayPassageIdIn(passageIdList);
                List<PayPassageAccount> payPassageAccounts = passageAccountMapper.selectByExample(passageAccountExample);
                accountIdList = payPassageAccounts.stream().map(PayPassageAccount::getPassageMchId).collect(Collectors.toList());
            }
        }
        if (CollectionUtils.isEmpty(accountIdList)) {
            return null;
        }
        return codeUserMapper.getByPassageIds(accountIdList);
    }

    void setCriteria(MchPayPassageExample.Criteria criteria, MchPayPassage obj) {
        if (obj != null) {
            if (obj.getMchId() != null) criteria.andMchIdEqualTo(obj.getMchId());
            if (obj.getProductId() != null) criteria.andProductIdEqualTo(obj.getProductId());
            if (obj.getStatus() != null && obj.getStatus().byteValue() != -99)
                criteria.andStatusEqualTo(obj.getStatus());
        }
    }
}
